#include "commtraff_stress_test.h"
#include "commtraff.h"
#include "commtraff_info_print.h"
#include "commtraff_mock.h"
#include "commtraff_tool_com.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>

#define TOOL_LIST_WIDTH 56
#define SECONDS_PER_HOUR 3600

// 流量类型名称数组
extern const char *traffic_type_names[];

// 生成指定范围内的随机间隔时间（秒）
int GenerateRandomInterval(int min_seconds, int max_seconds) {
    if (min_seconds >= max_seconds) {
        return min_seconds;
    }
    return min_seconds + (rand() % (max_seconds - min_seconds + 1));
}

// 打印间隔模式选择菜单
void PrintIntervalModes(void) {
    PrintTooLName("Select interval mode");
    printf("| %d - %-*s     |\r\n", INTERVAL_FIXED, TOOL_LIST_WIDTH - 11, "Fixed interval");
    printf("| %d - %-*s     |\r\n", INTERVAL_RANDOM, TOOL_LIST_WIDTH - 11, "Random interval");
    printf("| %d - %-*s     |\r\n", 0, TOOL_LIST_WIDTH - 11, "Back to traffic type selection");
    PrintLine(TOOL_LIST_WIDTH);
    printf("\n");
    printf("Enter interval mode: ");
    fflush(stdout);
}

// 执行指定类型的Mock插入
void ExecuteMockTraffInsertion(int traff_type) {
    switch (traff_type) {
        case 1:  // LINK_LAYER_DATA
            MockLinkTraff();
            break;
        case 2:  // TRANSPORT_LAYER_DATA
            MockTransportTraff();
            break;
        case 3:  // SESSION_LAYER_DATA
            MockSessionTraff();
            break;
        case 4:  // RPC_LAYER_DATA
            MockRpcTraff();
            break;
        case 5:  // WPA_LAYER_DATA
            MockWpaTraff();
            break;
        case 6:  // HISYSEVENT_DATA
            MockHisyseventTraff();
            break;
        default:
            printf("Invalid traffic type!\n");
            break;
    }
}

// 简化的查询结果回调函数，用于定时读取
void OnTimedQuery(CommTraff* records, int32_t nums) {
    int valid_records = 0;
    for (int i = 0; i < nums; i++) {
        // 检查记录中的数字字段是否全为0
        bool is_all_zero = false;
        CommTraff *record = &records[i];

        switch (record->traffType) {
            case LINK_LAYER_DATA: {
                LinkTraff *link = &record->data.linkTraff;
                is_all_zero = (link->txBytes == 0 && link->txPackets == 0 &&
                               link->rxBytes == 0 && link->rxPackets == 0 &&
                               link->rxErrPackets == 0 && link->txErrPackets == 0 &&
                               link->rxDropPackets == 0 && link->txDropPackets == 0);
                break;
            }
            case TRANSPORT_LAYER_DATA: {
                TransportTraff *transport = &record->data.transportTraff;
                is_all_zero = (transport->pid == 0 && transport->time == 0 &&
                               transport->sockId == 0 && transport->protocol == 0 &&
                               transport->sendBytes == 0 && transport->sendPacks == 0 &&
                               transport->recvBytes == 0 && transport->recvPacks == 0);
                break;
            }
            case SESSION_LAYER_DATA: {
                SessionTraff *session = &record->data.sessionTraff;
                is_all_zero = (session->pid == 0 && session->time == 0 &&
                               session->handle == 0 && session->channelId == 0 &&
                               session->connId == 0 && session->sessionId == 0 &&
                               session->sessionType == 0 &&
                               session->sendBytes == 0 && session->recvBytes == 0);
                break;
            }
            case RPC_LAYER_DATA: {
                RpcTraff *rpc = &record->data.rpcTraff;
                is_all_zero = (rpc->proxyHandle == 0 && rpc->stubHandle == 0 &&
                               rpc->sendDataLen == 0 && rpc->recvDataLen == 0 &&
                               rpc->recvDataSeq == 0 && rpc->sendDataSeq == 0);
                break;
            }
            case WPA_LAYER_DATA: {
                WpaTraff *wpa = &record->data.wpaTraff;
                is_all_zero = (wpa->signal == 0 && wpa->noise == 0 && wpa->snr == 0 &&
                               wpa->txrate == 0 && wpa->rxrate == 0 && wpa->realTxrate == 0 &&
                               wpa->realRxrate == 0 && wpa->txEfficiency == 0 && wpa->frequency == 0 &&
                               wpa->txPackets == 0 && wpa->rxPackets == 0 && wpa->chload == 0 &&
                               wpa->txBytes == 0 && wpa->rxBytes == 0 && wpa->txFailed == 0 &&
                               wpa->txRetries == 0);
                break;
            }
            case HISYSEVENT_DATA: {
                break;
            }
            default:
                is_all_zero = 1; // 对于未知类型，视为全零处理
                break;
        }

        // 只统计非零记录
        if (!is_all_zero) {
            valid_records++;
        }
    }
    // 简化的输出，只显示统计信息
    printf("Found %d valid records (total %d)\n", valid_records, nums);
}

// 简化的查询完成回调，用于定时读取
void OnTimedComplete(int32_t reason, int32_t total) {
    // 静默处理，不输出菜单
    if (reason != COMMTRAFF_SUCCESS) {
        printf("Query failed with reason code: %d\n", reason);
    }
}

// 执行指定类型的流量查询
void ExecuteTraffQuery(int traff_type) {
    CommTraffQueryRule queryRule = {0};
    queryRule.traffType = (TraffType)(traff_type - 1);

    // 设置查询最近1小时的记录
    time_t now = time(NULL);
    queryRule.startTime = now - SECONDS_PER_HOUR;
    queryRule.endTime = now;

    CommTraffQueryCb cb = {0};
    cb.OnQuery = OnTimedQuery;
    cb.OnComplete = OnTimedComplete;

    int32_t result = QueryCommTraff(&queryRule, &cb);
    if (result != COMMTRAFF_SUCCESS) {
        printf("Query failed with error code: %d for %s\n", result, traffic_type_names[traff_type - 1]);
    }
}

// 执行所有类型的Mock插入
void ExecuteAllTypeMockInsertion(void) {
    MockLinkTraff();
    MockTransportTraff();
    MockSessionTraff();
    MockRpcTraff();
    MockWpaTraff();
    MockHisyseventTraff();
}

// 执行所有类型的流量查询
void ExecuteAllTypeTraffQuery(void) {
    for (int i = 1; i <= 6; i++) {
        printf("Querying %s: ", traffic_type_names[i - 1]);
        fflush(stdout);
        ExecuteTraffQuery(i);
    }
}

// 处理固定间隔插入
void HandleFixedIntervalInsertion(int traff_type) {
    printf("Enter fixed interval time in seconds (1-3600): ");
    fflush(stdout);
    long interval_seconds = SafeReadLong(3600);
    if (interval_seconds == 0) {
        interval_seconds = 1; // 最小间隔为1秒
    }

    printf("Starting mock %s data insertion with %ld second fixed interval (Press Ctrl+C to stop)...\n",
           traffic_type_names[traff_type - 1], interval_seconds);

    int count = 0;
    while (1) {
        ExecuteMockTraffInsertion(traff_type);
        count++;
        printf("Inserted record #%d, waiting %ld seconds for next insertion...\n", count, interval_seconds);
        fflush(stdout); // 确保输出立即显示
        sleep(interval_seconds);
    }
}

// 处理随机间隔插入
void HandleRandomIntervalInsertion(int traff_type) {
    printf("Enter minimum interval time in seconds (1-3600): ");
    fflush(stdout);
    long min_interval = SafeReadLong(3600);
    if (min_interval == 0) {
        min_interval = 1; // 最小间隔为1秒
    }

    printf("Enter maximum interval time in seconds (%ld-3600): ", min_interval);
    fflush(stdout);
    long max_interval = SafeReadLong(3600);
    if (max_interval < min_interval) {
        max_interval = min_interval;
    }

    printf("Starting mock %s data insertion with random interval [%ld, %ld] seconds (Press Ctrl+C to stop)...\n",
           traffic_type_names[traff_type - 1], min_interval, max_interval);

    int count = 0;
    while (1) {
        ExecuteMockTraffInsertion(traff_type);
        count++;

        int current_interval = GenerateRandomInterval((int)min_interval, (int)max_interval);
        printf("Inserted record #%d, waiting %d seconds (random) for next insertion...\n", count, current_interval);
        fflush(stdout); // 确保输出立即显示
        sleep(current_interval);
    }
}

// 处理固定间隔读取
void HandleFixedIntervalRead(int traff_type) {
    printf("Enter fixed interval time in seconds (1-3600): ");
    fflush(stdout);
    long interval_seconds = SafeReadLong(3600);
    if (interval_seconds == 0) {
        interval_seconds = 1; // 最小间隔为1秒
    }

    printf("Starting timed %s data reading with %ld second fixed interval (Press Ctrl+C to stop)...\n",
           traffic_type_names[traff_type - 1], interval_seconds);

    int count = 0;
    while (1) {
        printf("Read #%d - ", count + 1);
        ExecuteTraffQuery(traff_type);
        count++;
        printf("Waiting %ld seconds for next read...\n", interval_seconds);
        fflush(stdout); // 确保输出立即显示
        sleep(interval_seconds);
    }
}

// 处理随机间隔读取
void HandleRandomIntervalRead(int traff_type) {
    printf("Enter minimum interval time in seconds (1-3600): ");
    fflush(stdout);
    long min_interval = SafeReadLong(3600);
    if (min_interval == 0) {
        min_interval = 1; // 最小间隔为1秒
    }

    printf("Enter maximum interval time in seconds (%ld-3600): ", min_interval);
    fflush(stdout);
    long max_interval = SafeReadLong(3600);
    if (max_interval < min_interval) {
        max_interval = min_interval;
    }

    printf("Starting timed %s data reading with random interval [%ld, %ld] seconds (Press Ctrl+C to stop)...\n",
           traffic_type_names[traff_type - 1], min_interval, max_interval);

    int count = 0;
    while (1) {
        printf("Read #%d - ", count + 1);
        ExecuteTraffQuery(traff_type);
        count++;

        int current_interval = GenerateRandomInterval((int)min_interval, (int)max_interval);
        printf("Waiting %d seconds (random) for next read...\n", current_interval);
        fflush(stdout); // 确保输出立即显示
        sleep(current_interval);
    }
}

// 外部声明流量类型选择菜单
extern void PrintTraffTypes(void);

// 处理单类型定时插入（压力测试）
void HandleSingleTypeTimed(void) {
    while (1) {
        // 第一步：选择流量类型
        PrintTraffTypes();
        int traff_type = SafeReadInt(6);
        if (traff_type == 0) {
            break; // 返回主菜单
        }
        printf("Selected traffic type: %s\n", traffic_type_names[traff_type - 1]);

        // 第二步：选择间隔模式
        while (1) {
            PrintIntervalModes();
            int interval_mode = SafeReadInt(2);
            if (interval_mode == 0) {
                break; // 返回流量类型选择
            }

            switch (interval_mode) {
                case INTERVAL_FIXED:
                    HandleFixedIntervalInsertion(traff_type);
                    break;
                case INTERVAL_RANDOM:
                    HandleRandomIntervalInsertion(traff_type);
                    break;
                default:
                    printf("Invalid interval mode!\n");
                    continue;
            }
        }
    }
}

// 处理单类型定时读取
void HandleSingleTypeRead(void) {
    while (1) {
        // 第一步：选择流量类型
        PrintTraffTypes();
        int traff_type = SafeReadInt(6);
        if (traff_type == 0) {
            break; // 返回主菜单
        }
        printf("Selected traffic type: %s\n", traffic_type_names[traff_type - 1]);

        // 第二步：选择间隔模式
        while (1) {
            PrintIntervalModes();
            int interval_mode = SafeReadInt(2);
            if (interval_mode == 0) {
                break; // 返回流量类型选择
            }

            switch (interval_mode) {
                case INTERVAL_FIXED:
                    HandleFixedIntervalRead(traff_type);
                    break;
                case INTERVAL_RANDOM:
                    HandleRandomIntervalRead(traff_type);
                    break;
                default:
                    printf("Invalid interval mode!\n");
                    continue;
            }
        }
    }
}

// 处理批量插入（所有类型）
void HandleBatchInsertion(void) {
    while (1) {
        PrintIntervalModes();
        int interval_mode = SafeReadInt(2);
        if (interval_mode == 0) {
            break; // 返回主菜单
        }

        switch (interval_mode) {
            case INTERVAL_FIXED: {
                printf("Enter fixed interval time in seconds (1-3600): ");
                fflush(stdout);
                long interval_seconds = SafeReadLong(3600);
                if (interval_seconds == 0) {
                    interval_seconds = 1; // 最小间隔为1秒
                }

                printf("Starting batch insertion of all traffic types with %ld second fixed interval (Press Ctrl+C to stop)...\n",
                       interval_seconds);

                int count = 0;
                while (1) {
                    ExecuteAllTypeMockInsertion();
                    count++;
                    printf("Batch #%d: Inserted all 6 traffic types, waiting %ld seconds for next batch...\n",
                           count, interval_seconds);
                    fflush(stdout); // 确保输出立即显示
                    sleep(interval_seconds); // 转换为秒
                }
            }
            case INTERVAL_RANDOM: {
                printf("Enter minimum interval time in seconds (1-3600): ");
                fflush(stdout);
                long min_interval = SafeReadLong(3600);
                if (min_interval == 0) {
                    min_interval = 1; // 最小间隔为1秒
                }

                printf("Enter maximum interval time in seconds (%ld-3600): ", min_interval);
                fflush(stdout);
                long max_interval = SafeReadLong(3600);
                if (max_interval < min_interval) {
                    max_interval = min_interval;
                }

                printf("Starting batch insertion of all traffic types with random interval [%ld, %ld] seconds (Press Ctrl+C to stop)...\n",
                       min_interval, max_interval);

                int count = 0;
                while (1) {
                    ExecuteAllTypeMockInsertion();
                    count++;

                    int current_interval = GenerateRandomInterval((int)min_interval, (int)max_interval);
                    printf("Batch #%d: Inserted all 6 traffic types, waiting %d seconds (random) for next batch...\n",
                           count, current_interval);
                    fflush(stdout); // 确保输出立即显示
                    sleep(current_interval);
                }
            }
            default:
                printf("Invalid interval mode!\n");
                continue;
        }
    }
}

// 处理批量读取（所有类型）
void HandleBatchRead(void) {
    while (1) {
        PrintIntervalModes();
        int interval_mode = SafeReadInt(2);
        if (interval_mode == 0) {
            break; // 返回主菜单
        }

        switch (interval_mode) {
            case INTERVAL_FIXED: {
                printf("Enter fixed interval time in seconds (1-3600): ");
                fflush(stdout);
                long interval_seconds = SafeReadLong(3600);
                if (interval_seconds == 0) {
                    interval_seconds = 1; // 最小间隔为1秒
                }

                printf("Starting batch reading of all traffic types with %ld second fixed interval (Press Ctrl+C to stop)...\n",
                       interval_seconds);

                int count = 0;
                while (1) {
                    printf("Batch read #%d:\n", count + 1);
                    ExecuteAllTypeTraffQuery();
                    count++;
                    printf("Waiting %ld seconds for next batch read...\n", interval_seconds);
                    fflush(stdout); // 确保输出立即显示
                    sleep(interval_seconds);
                }
            }
            case INTERVAL_RANDOM: {
                printf("Enter minimum interval time in seconds (1-3600): ");
                fflush(stdout);
                long min_interval = SafeReadLong(3600);
                if (min_interval == 0) {
                    min_interval = 1; // 最小间隔为1秒
                }

                printf("Enter maximum interval time in seconds (%ld-3600): ", min_interval);
                fflush(stdout);
                long max_interval = SafeReadLong(3600);
                if (max_interval < min_interval) {
                    max_interval = min_interval;
                }

                printf("Starting batch reading of all traffic types with random interval [%ld, %ld] seconds (Press Ctrl+C to stop)...\n",
                       min_interval, max_interval);

                int count = 0;
                while (1) {
                    printf("Batch read #%d:\n", count + 1);
                    ExecuteAllTypeTraffQuery();
                    count++;

                    int current_interval = GenerateRandomInterval((int)min_interval, (int)max_interval);
                    printf("Waiting %d seconds (random) for next batch read...\n", current_interval);
                    fflush(stdout); // 确保输出立即显示
                    sleep(current_interval);
                }
            }
            default:
                printf("Invalid interval mode!\n");
                continue;
        }
    }
}

// 打印高级配置菜单
void PrintAdvancedConfigMenu(AdvancedConfig configs[]) {
    PrintTooLName("Advanced Multi-Type Configuration");
    printf("Current configuration:\n");
    for (int i = 0; i < 6; i++) {
        printf("| %d - %-20s: %s (interval: %ds)     |\r\n",
               i + 1,
               configs[i].name,
               configs[i].enabled ? "Enabled" : "Disabled",
               configs[i].interval);
    }
    printf("| %d - %-*s     |\r\n", 7, TOOL_LIST_WIDTH - 11, "Start with current config");
    printf("| %d - %-*s     |\r\n", 0, TOOL_LIST_WIDTH - 11, "Back to stress test menu");
    PrintLine(TOOL_LIST_WIDTH);
    printf("\n");
    printf("Enter option (1-6 to configure, 7 to start, 0 to exit): ");
    fflush(stdout);
}

// 处理高级多类型插入
void HandleAdvancedInsertion(void) {
    // 初始化配置
    AdvancedConfig configs[6] = {
            {1, 5, 0, "Link Layer Data"},      // 默认启用，5秒间隔
            {1, 8, 0, "Transport Layer Data"}, // 默认启用，8秒间隔
            {1, 10, 0, "Session Layer Data"},   // 默认启用，10秒间隔
            {1, 15, 0, "RPC Layer Data"},       // 默认启用，15秒间隔
            {1, 12, 0, "WPA Layer Data"},       // 默认启用，12秒间隔
            {0, 20, 0, "HISYSEVENT Data"}       // 默认禁用，20秒间隔
    };

    while (1) {
        PrintAdvancedConfigMenu(configs);
        int choice = SafeReadInt(7);

        if (choice == 0) {
            break; // 返回主菜单
        } else if (choice >= 1 && choice <= 6) {
            // 配置特定类型
            int idx = choice - 1;
            printf("Configure %s:\n", configs[idx].name);
            printf("Current: %s, interval: %ds\n",
                   configs[idx].enabled ? "Enabled" : "Disabled",
                   configs[idx].interval);

            printf("Enable this type? (1=Yes, 0=No): ");
            fflush(stdout);
            configs[idx].enabled = SafeReadInt(1);

            if (configs[idx].enabled) {
                printf("Enter interval in seconds (1-3600): ");
                fflush(stdout);
                configs[idx].interval = (int)SafeReadLong(3600);
                if (configs[idx].interval == 0) {
                    configs[idx].interval = 1;
                }
            }
            configs[idx].next_insert = 0; // 重置计时器

            // 显示配置更新提示
            printf("\nConfiguration updated successfully!\n");
            printf("Press Enter to continue...");
            fflush(stdout);

            // 安全地等待用户按回车
            char dummy[8];
            if (fgets(dummy, sizeof(dummy), stdin) == NULL) {
                // 处理输入错误，但继续执行
            }
            printf("\n");

        } else if (choice == 7) {
            // 开始插入
            printf("Starting advanced multi-type insertion (Press Ctrl+C to stop)...\n");
            printf("Configuration summary:\n");
            for (int i = 0; i < 6; i++) {
                if (configs[i].enabled) {
                    printf("  %s: every %d seconds\n", configs[i].name, configs[i].interval);
                }
            }
            printf("\n");

            // 重置所有计时器
            for (int i = 0; i < 6; i++) {
                configs[i].next_insert = 0;
            }

            int global_time = 0;
            int total_insertions = 0;

            while (1) {
                bool any_inserted = false;

                // 检查每种类型是否需要插入
                for (int i = 0; i < 6; i++) {
                    if (configs[i].enabled && global_time >= configs[i].next_insert) {
                        // 执行插入
                        ExecuteMockTraffInsertion(i + 1); // i+1 because ExecuteMockTraffInsertion expects 1-based index

                        printf("T+%03ds: Inserted %s (next in %ds)\n",
                               global_time, configs[i].name, configs[i].interval);

                        // 设置下次插入时间
                        configs[i].next_insert = global_time + configs[i].interval;
                        total_insertions++;
                        any_inserted = true;
                    }
                }

                if (!any_inserted) {
                    printf("T+%03ds: Waiting... (Total insertions: %d)\r", global_time, total_insertions);
                    fflush(stdout);
                }

                sleep(1);
                global_time++;
            }
        } else {
            printf("Invalid option!\n");
        }
    }
}

// 处理高级多类型读取
void HandleAdvancedRead(void) {
    // 初始化配置
    AdvancedConfig configs[6] = {
            {1, 10, 0, "Link Layer Data"},      // 默认启用，10秒间隔
            {1, 15, 0, "Transport Layer Data"}, // 默认启用，15秒间隔
            {1, 20, 0, "Session Layer Data"},   // 默认启用，20秒间隔
            {1, 30, 0, "RPC Layer Data"},       // 默认启用，30秒间隔
            {1, 25, 0, "WPA Layer Data"},       // 默认启用，25秒间隔
            {0, 60, 0, "HISYSEVENT Data"}       // 默认禁用，60秒间隔
    };

    while (1) {
        PrintAdvancedConfigMenu(configs);
        int choice = SafeReadInt(7);

        if (choice == 0) {
            break; // 返回主菜单
        } else if (choice >= 1 && choice <= 6) {
            // 配置特定类型
            int idx = choice - 1;
            printf("Configure reading for %s:\n", configs[idx].name);
            printf("Current: %s, interval: %ds\n",
                   configs[idx].enabled ? "Enabled" : "Disabled",
                   configs[idx].interval);

            printf("Enable reading for this type? (1=Yes, 0=No): ");
            fflush(stdout);
            configs[idx].enabled = SafeReadInt(1);

            if (configs[idx].enabled) {
                printf("Enter read interval in seconds (1-3600): ");
                fflush(stdout);
                configs[idx].interval = (int)SafeReadLong(3600);
                if (configs[idx].interval == 0) {
                    configs[idx].interval = 1;
                }
            }
            configs[idx].next_insert = 0; // 重置计时器

            // 显示配置更新提示
            printf("\nConfiguration updated successfully!\n");
            printf("Press Enter to continue...");
            fflush(stdout);

            // 安全地等待用户按回车
            char dummy[8];
            if (fgets(dummy, sizeof(dummy), stdin) == NULL) {
                // 处理输入错误，但继续执行
            }
            printf("\n");

        } else if (choice == 7) {
            // 开始读取
            printf("Starting advanced multi-type reading (Press Ctrl+C to stop)...\n");
            printf("Read configuration summary:\n");
            for (int i = 0; i < 6; i++) {
                if (configs[i].enabled) {
                    printf("  %s: every %d seconds\n", configs[i].name, configs[i].interval);
                }
            }
            printf("\n");

            // 重置所有计时器
            for (int i = 0; i < 6; i++) {
                configs[i].next_insert = 0;
            }

            int global_time = 0;
            int total_reads = 0;

            while (1) {
                bool any_read = false;

                // 检查每种类型是否需要读取
                for (int i = 0; i < 6; i++) {
                    if (configs[i].enabled && global_time >= configs[i].next_insert) {
                        // 执行读取
                        printf("T+%03ds: Reading %s - ", global_time, configs[i].name);
                        ExecuteTraffQuery(i + 1);
                        printf("(next read in %ds)\n", configs[i].interval);

                        // 设置下次读取时间
                        configs[i].next_insert = global_time + configs[i].interval;
                        total_reads++;
                        any_read = true;
                    }
                }

                if (!any_read) {
                    printf("T+%03ds: Waiting... (Total reads: %d)\r", global_time, total_reads);
                    fflush(stdout);
                }

                sleep(1);
                global_time++;
            }
        } else {
            printf("Invalid option!\n");
        }
    }
}
